<template>
  <div class="v-property-tags">
    <div
      class="g-toolbar-between"
      :class="[$global.isIpcWindow ? '_BackGroundWhite is_ipc' : '__BackGroundGrey']"
    >
      <div class="g-toolbar-left">
        <span
          class="g-img-box"
          @click="handelSpread"
        >
          <img src="statics/icons/app/iconspread.svg" />
        </span>
        <span
          class="g-img-box"
          @click="handleShrink"
        >
          <img src="statics/icons/app/iconshrink.svg" />
        </span>
        <span
          class="g-img-box"
          :class="{ active: searchActive }"
          @click="handleSearch"
        >
          <img src="statics/icons/app/iconsearch.svg" />
        </span>
      </div>
    </div>

    <div
      v-show="searchActive"
      class="search-area g-m-l-10 g-m-b-10"
    >
      <el-input
        v-model="query"
        :placeholder="$t('搜索')"
      >
        <template #prefix>
          <el-icon class="el-input__icon"><search /></el-icon>
        </template>
      </el-input>
    </div>
    <div class="table-container g-pd-l-10">
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="filteredTableData"
        :style="{ width: '100%', height: 'calc(100% - 44px)', 'margin-bottom': '16px' }"
        row-key="id"
        :indent="0"
        :empty-text="$t('暂无数据')"
        :element-loading-text="$t('加载中') + '...'"
        border
        :expand-row-keys="expandRowKeys"
        :cell-class-name="cellClassName"
        :span-method="arraySpanMethod"
        highlight-current-row
      >
        <el-table-column
          v-for="column in columns"
          :key="column.prop"
          :prop="column.prop"
          :label="$t(column.label)"
          :resizable="column.resizable"
          :width="column.width"
          :align="column.align"
        >
          <template #default="{ row }: { row: TableRow }">
            <div
              v-if="column.prop === 'active'"
              class="g-one-line cell-box"
            >
              <span
                v-if="row.mergeRows"
                class="text"
              >
                {{ $t(row.cnName || "") }}
              </span>
              <el-checkbox
                v-else
                :model-value="activeRow?.id === row.id"
                size="large"
                :disabled="isModelDisabled"
                @change="changeActiveLinkId(row)"
              />
            </div>
            <div
              v-else-if="column.prop === 'name'"
              class="g-one-line cell-box"
            >
              {{ $t(row.label || row.cnName || "") }}
            </div>
            <div
              v-else-if="column.prop === 'type'"
              class="g-one-line cell-box"
            >
              <img
                v-if="row.typeInfo?.icon"
                :src="row.typeInfo?.icon"
                alt=""
                style="height: 16px; width: 16px"
              />
              <span class="text">{{ $t(row.typeInfo?.name || "") }}</span>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div class="g-footer-button _footer-button">
        <!--<el-button :disabled="!currentRow" @click="openHyperlink">
        // 等到后面做了窗口的前进和后退再放开这个按钮
          <img src="statics/icons/app/iconadd.svg" alt="">
          {{$t('打开')}}
        </el-button>-->
        <MButton
          type="edit"
          text="编辑"
          :disabled="!currentRow"
          @click="editHyperlink"
        />
        <MButton
          type="add"
          text="添加"
          :disabled="isModelDisabled"
          @click="addHyperlink"
        />
        <MButton
          type="delete"
          text="移除"
          :disabled="!currentRow"
          @click="deleteHyperlink"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, inject, Ref } from "vue";
import type { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults";
import { addHyperlinkWindow } from "@/modules/model/modals/addHyperlink";
import { PropertyKey, PropertyDataType, LinkType } from "@/constants/Enums";
import { modelService } from "@/modules/model/service";
import { UpdateModelPropertyDto } from "@/modules/model/comps/station/sider/attribute/types";
import { getUid } from "@/util/common";
import { Search } from "@element-plus/icons-vue";
import { Link, HyperLinkInfo, HyperLinkIdType } from "./types";
import { ModelData } from "@/constants/types";
import { storage, StorageKey } from "@/util/Storage";
import MButton from "@/common/button/Button.vue";

interface TableRow {
  id: string; // uuid or groupId
  cnName?: string;
  enName?: string;
  label?: string;
  mergeRows?: boolean;
  link?: Link;
  children?: TableRow[];
  group?: HyperLinkIdType;
  typeInfo?: { icon: string; name: string };
}

interface SpanMethodProps {
  row: TableRow;
  column: TableColumnCtx<Column>;
  rowIndex: number;
  columnIndex: number;
}

interface Column {
  label: string;
  prop: string;
  resizable: boolean;
  width?: number;
  align: "left" | "center" | "right";
}
const isModelDisabled = inject("isModelDisabled") as Ref<boolean>;

const routeQuery = app.$route.query as { projectId: string; modelId: string; groupId: string; activeKey: string };

let modelId = routeQuery.modelId;
const projectId = routeQuery.projectId;

const searchActive = ref(false);
const query = ref("");
const expandRowKeys = ref<string[]>(["general", "ownedDiagram", "typedOwnedDiagram", "hyperlink"]); // 当前展开行的key
const loading = ref(false);

const defaultRow: TableRow[] = [
  {
    id: "general",
    cnName: "通用",
    enName: "General",
    mergeRows: true,
    children: [
      {
        id: "default",
        cnName: "默认导航",
        enName: "Default Navigation",
        group: "default"
      },
      {
        id: "specification",
        cnName: "属性设置窗口",
        enName: "Specification",
        group: "default"
      }
    ]
  },
  {
    id: "ownedDiagram",
    cnName: "已有图表",
    enName: "Owned Diagrams",
    mergeRows: true,
    children: []
  },
  {
    id: "typedOwnedDiagram",
    cnName: "类型的已有图表",
    enName: "Diagrams Owned By Type",
    mergeRows: true,
    children: []
  },
  {
    id: "hyperlink",
    cnName: "超链接",
    enName: "Hyperlink",
    mergeRows: true,
    children: []
  }
];
const tableRowData = ref<TableRow[]>(defaultRow);
const tableRef = ref<any>(null);
// 判断当前鼠标选中哪一行
const currentRow = computed(() => {
  const row = tableRef.value?.store.states?.currentRow.value as TableRow;
  if (row?.group === "hypereLink") {
    return row;
  }
  return undefined;
});

// 选中的默认导航
const defaultActiveRow = tableRowData.value.find(row => row.id === "general")?.children?.find(item => item.id === "default");
// 选择的导航
const activeRow = ref<TableRow | undefined>();

const filteredTableData = computed(() => {
  const rows = tableRowData.value
    .filter(row => row.children?.length)
    .filter(Boolean)
    .map(it => ({ ...it }));
  if (query.value) {
    rows.forEach(row => {
      row.children = row.children?.filter(it => it.label?.toLocaleLowerCase().includes(query.value));
    });
  }
  return rows;
});

const columns: Column[] = [
  {
    label: "models.active",
    prop: "active",
    resizable: true,
    align: "left",
    width: 60
  },
  {
    label: "名称",
    prop: "name",
    resizable: true,
    align: "left"
  },
  {
    label: "类型",
    prop: "type",
    resizable: false,
    align: "left"
  }
];

const arraySpanMethod = (d: SpanMethodProps) => {
  const { row, columnIndex } = d;
  if (row.mergeRows) {
    if (columnIndex === 0) {
      return [1, 3];
    } else {
      return [0, 0];
    }
  }
  return [1, 1];
};

async function loadData() {
  await loadOwnedDiagrams();
  await loadHyperlinks();
}
loadData();
async function loadOwnedDiagrams() {
  const res = await modelService.queryElementOwnedDiagram(projectId, modelId);
  const ownedDiagram = tableRowData.value.find(it => it.id === "ownedDiagram")!;
  const typedOwnedDiagram = tableRowData.value.find(it => it.id === "typedOwnedDiagram")!;
  res.existedDiagram?.forEach(item => {
    ownedDiagram.children?.push({
      id: item.instanceId,
      cnName: item.name,
      label: item.name,
      group: "ownedDiagramId",
      typeInfo: { name: item.cnType, icon: item.icon }
    });
  });
  res.typeElementExistedDiagram?.forEach(item => {
    typedOwnedDiagram.children?.push({
      id: item.instanceId,
      cnName: item.name,
      label: item.name,
      group: "typedOwnedDiagramId",
      typeInfo: { name: item.cnType, icon: item.icon }
    });
  });
}

async function loadHyperlinks() {
  const propertyValue = (await modelService
    .getPropertyValueById(projectId, modelId, PropertyKey.Element_activeHyperLink)
    .then(data => JSON.parse((data as string) || "{}"))) as HyperLinkInfo;
  if (propertyValue.links) {
    const children = tableRowData.value.find(it => it.id === "hyperlink")?.children || [];
    const length = propertyValue.links.length;
    for (let i = 0; i < length; i++) {
      const link = propertyValue.links[i];
      let typeInfo;
      let label = link.url;
      if (link.type === LinkType.MODEL) {
        // 如果是模型类型，需要根据id去查一下name，因为name可能被编辑，所以这里只存了id
        const linkModel: ModelData = await modelService.getModelData(projectId, link.url);
        label = linkModel.name;
        typeInfo = getTypeInfo(link, linkModel);
      } else {
        typeInfo = getTypeInfo(link);
      }
      children.push({
        id: link.id,
        link: link,
        group: "hypereLink",
        label: label,
        typeInfo: typeInfo
      });
    }
  }
  if (propertyValue.activeId) {
    for (let i = 0; i < tableRowData.value.length; i++) {
      const parentRow = tableRowData.value[i];
      if (parentRow && parentRow.children) {
        for (let j = 0; j < parentRow.children.length; j++) {
          if (parentRow.children[j].id === propertyValue.activeId) {
            activeRow.value = parentRow.children[j];
          }
        }
      }
    }
  }
  if (!activeRow.value) {
    activeRow.value = defaultActiveRow;
  }
}
const getTypeInfo = (link: Link, modelData?: ModelData, modelIcon?: string, modelTypeCnName?: string) => {
  let typeInfo = { name: "", icon: "" };
  if (modelData && modelData.icon && modelData.modelTypeCnName) {
    return { icon: modelData.icon, name: modelData.modelTypeCnName };
  }
  if (modelIcon && modelTypeCnName) {
    return { icon: modelIcon, name: modelTypeCnName };
  }
  if (link.type === LinkType.URL) {
    typeInfo = {
      icon: "/statics/icons/attrTip/iconlink.svg",
      name: "链接"
    };
  } else if (link.type === LinkType.FILE) {
    typeInfo = {
      icon: "/statics/icons/attrTip/iconfile.svg",
      name: "文件"
    };
    if (link.url.endsWith(".jpg") || link.url.endsWith(".png") || link.url.endsWith(".gif") || link.url.endsWith(".svg")) {
      typeInfo = {
        icon: "/statics/icons/attrTip/iconpng.svg",
        name: "文件"
      };
    }
  }
  return typeInfo;
};

// 切换默认导航
async function changeActiveLinkId(row: TableRow) {
  activeRow.value = row;
  await submitData();
}

function getValueData(): HyperLinkInfo {
  const links = tableRowData.value.find(it => it.id === "hyperlink")?.children || [];
  return {
    activeId: activeRow.value?.id || null,
    idType: activeRow.value?.group || null,
    links: links.map(it => it.link!).filter(Boolean)
  };
}

async function submitData() {
  const valueData = getValueData();
  const dto: UpdateModelPropertyDto = {
    projectId,
    key: PropertyKey.Element_activeHyperLink,
    value: JSON.stringify(valueData),
    dataType: PropertyDataType.STRING,
    instanceId: modelId,
    isMultiplicity: false
  };
  await modelService.updateModelProperty(dto);
}

const handelSpread = () => {
  expandRowKeys.value = ["general", "ownedDiagram", "typedOwnedDiagram", "hyperlink"];
};

const handleShrink = () => {
  expandRowKeys.value = [];
};

const handleSearch = () => {
  searchActive.value = !searchActive.value;
  if (!searchActive.value) {
    query.value = "";
  }
};

const cellClassName = (d: SpanMethodProps) => {
  const { row, columnIndex } = d;
  if (row.mergeRows) return "merge-rows";
  if (columnIndex === 0) return "first-column";
  return "";
};

// 打开超链接
// const openHyperlink = async () => {
//   if (currentRow.value?.link?.type === LinkType.URL) {
//     shell.openExternal(currentRow.value?.link.url);
//   } else if (currentRow.value?.link?.type === LinkType.FILE) {
//     shell.openPath(currentRow.value?.link.url);
//   } else if (currentRow.value?.link?.type === LinkType.MODEL) {
//     const model: ModelData = await modelService.getModelData(projectId, currentRow.value?.link.url);
//     if (model.baseSt && modelUtil.isStDiagram(model.baseSt)) {
//       (actionManager.getAction(ActionKey.openDiagram) as OpenDiagramAction).run(model);
//     } else {
//       (actionManager.getAction(ActionKey.showAttribute) as ShowAttributeAction).run(model);
//     }
//   }
// };
// 编辑超链接
const editHyperlink = async () => {
  // 编辑和新增共用一个窗口
  storage.set(StorageKey.latestVisitedLinkTab, currentRow.value?.link?.type);
  const data: any = await addHyperlinkWindow.popup({
    attrTip: "addHyperlink",
    title: "编辑超链接",
    projectId: projectId,
    modelId: modelId,
    currentTab: currentRow.value?.link?.type,
    url: currentRow.value?.link?.url
  });
  if (!data.success) {
    return;
  }
  const hyperlinkRow = tableRowData.value.find(item => item.id === "hyperlink")!;
  const row = hyperlinkRow.children?.find(item => item.id === currentRow.value?.link?.id);
  if (!row || !row.link) {
    return;
  }
  // 三种类型的url是不可能重复，所以这里校验一下url有没有发生变化就好
  if (data.url === row.link.url) {
    return;
  }
  if (!checkReduplicated(data.url, hyperlinkRow)) {
    return;
  }
  row.label = data.url;
  if (row.link) {
    row.link.type = data.type;
    row.link.url = data.url;
  }

  row.typeInfo = getTypeInfo(row.link, undefined, data.modelIcon, data.modelTypeCnName);
  // 因为模型导航的url是模型id
  if (data.modelName) {
    row.label = data.modelName;
  }
  changeActiveLinkId(row);
  submitData();
};
// 添加超链接
const addHyperlink = async () => {
  const data = await addHyperlinkWindow.popup({
    attrTip: "addHyperlink",
    title: "新增超链接",
    projectId: projectId,
    modelId: modelId
  });
  if (!data.success) {
    return;
  }
  const hyperlinkRow: TableRow = tableRowData.value.find(item => item.id === "hyperlink")!;
  if (!checkReduplicated(data.url, hyperlinkRow)) {
    return false;
  }

  const uid = getUid();
  const link: Link = {
    id: uid,
    type: data.type,
    url: data.url
  };
  const row: TableRow = {
    id: uid,
    label: data.type === LinkType.MODEL ? data.modelName || "" : data.url,
    typeInfo: getTypeInfo(link, undefined, data.modelIcon, data.modelTypeCnName),
    group: "hypereLink",
    link: link
  };
  hyperlinkRow.children?.push(row);
  changeActiveLinkId(row);
  submitData();
};
const checkReduplicated = (url: string, hyperlinkRow: TableRow) => {
  if (hyperlinkRow && hyperlinkRow.children && hyperlinkRow.children.find(item => item.link && item.link.url === url)) {
    // 模型已存在的话给予提示
    app.$notify({
      message: "该超链接已存在",
      title: "温馨提示",
      type: "warning"
    });
    return false;
  }
  return true;
};

// 移除超链接
function deleteHyperlink() {
  const hyperlinkRowParent = tableRowData.value.find(row => row.id === "hyperlink")!;
  const index = hyperlinkRowParent.children!.findIndex(it => it.id === currentRow.value?.id);
  if (index > -1) {
    hyperlinkRowParent.children?.splice(index, 1);
    if (activeRow.value?.id === currentRow.value?.id) {
      activeRow.value = undefined;
    }
    submitData();
  }
}
</script>

<style lang="scss">
@import "@/assets/css/theme.scss";
.v-property-tags {
  display: flex;
  flex-direction: column;
  height: 100%;
  ._attribute-header {
    height: 24px;
    display: flex;
    align-items: center;
    .operate-item {
      width: 24px;
      height: 24px;
      padding: 4px;
      margin-right: 2px;
      border: 1px solid #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      img {
        width: 14px;
        height: 14px;
      }
      &:hover {
        border: 1px solid $btn-border-color;
        background: $item-active-bg-color;
      }
      &.active {
        background: $item-active-bg-color;
        border: 1px solid #e0e0e0;
      }
    }
  }
  .search-area {
    .el-input__wrapper {
      border: 1px solid $btn-border-color;
      box-shadow: none;
      padding: 0 12px;
      .el-input__icon {
        margin-right: 5px;
      }
    }
  }
  .table-container {
    flex: 1;
    overflow: hidden;
    position: relative;
    .merge-rows {
      background-color: #fff;
    }
    .el-table--border {
      // &::after, &::before {
      //   width: 0;
      // }
      // .el-table__inner-wrapper {
      //   &::after, &::before {
      //     height: 0;
      //   }
      // }
    }
    .el-table__column-resize-proxy {
      border-color: $btn-border-color;
      border-width: 2px;
    }
    .el-table__border-left-patch {
      width: 0;
    }
    .el-table__header {
      border-top: 1px solid $btn-border-color;
      border-left: 1px solid $btn-border-color;

      table-layout: auto;
      .el-table__cell {
        background: $titlebar-bg-color;
        padding: 2px 0;
        border-bottom-color: $btn-border-color;
        border-right-color: $btn-border-color;
        // border-left: none;
        .cell {
          color: rgba(0, 0, 0, 0.85);
          font-weight: 500;
        }
      }
    }

    .el-table__body {
      // border-right: 1px solid $btn-border-color;
      // border-left: 1px solid $btn-border-color;

      tr {
        .el-table__cell {
          // &:first-of-type {
          //   border-left: 1px solid $btn-border-color;
          // }
          // &:last-of-type {
          //   border-right: 1px solid $btn-border-color;
          // }
          &.first-column {
            .cell {
              justify-content: center;
            }
          }
          padding: 0;
        }
        &.el-table__row--level-0 {
          background: var(--md-color-sub3);
        }
      }
    }
    .cell {
      line-height: 24px;
      white-space: nowrap;
      display: flex;
      align-items: center;
      .el-table__placeholder {
        display: none;
      }
      .cell-box {
        line-height: 24px;
        height: 24px;
        display: flex;
        align-items: center;
        > img {
          margin-right: 4px;
        }
        .el-checkbox {
          height: 24px;
        }
      }
      .el-table__expand-icon {
        vertical-align: middle;
        transform: none;
        margin-right: 4px;
        &::before {
          content: "";
          width: 12px;
          height: 12px;
          display: block;
          background: url("/statics/icons/app/iconadd.svg") no-repeat;
          background-size: cover;
        }
        &.el-table__expand-icon--expanded {
          &::before {
            background: url("/statics/icons/table/iconspread2.svg") no-repeat;
            background-size: cover;
          }
        }
        .el-icon {
          display: none;
        }
      }
      .text {
        text-overflow: ellipsis;
        white-space: nowrap;
        overflow: hidden;
        flex: 1;
      }
    }
    .el-table__empty-block {
      min-height: 24px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      flex-direction: column;
      align-items: center;
      &::before {
        content: "";
        width: 111px;
        height: 95px;
        background: url("/statics/icons/table/coworkfail.svg") no-repeat center;
        background-size: contain;
      }
      .el-table__empty-text {
        margin-top: 20px;
        line-height: 24px;
        width: 100%;
        color: rgba(0, 0, 0, 0.85);
      }
    }
  }
  ._footer-button {
    width: 100%;
    background: #fff;
  }
}
</style>
